package tuanda.soict.firstsun.AbilityPackage;

import java.util.ArrayList;

import tuanda.soict.firstsun.LogicPackage.Army;
import tuanda.soict.firstsun.LogicPackage.BattleMap;
import tuanda.soict.firstsun.LogicPackage.Coordinate;
import tuanda.soict.firstsun.LogicPackage.Group;
import tuanda.soict.firstsun.LogicPackage.Scenario;

/**
 * @author tuanda_soict_hut
 * @version 0.0.1
 * @since 13-9-2012
 */
public class Attack extends Ability {

	public Attack(int id, String name, int range, int area, int affect) {
		super(id, name, range, area, affect);
	}

	@Override
	public void mainAct(Army army, Scenario scenario) {
		Coordinate current = army.getCoordinate();
		int range = army.getTotalAttackRange();
		Coordinate targetCoor = this.getTarget();
		BattleMap map = scenario.getBattleMap();
		Group[] group = scenario.getGroup();
		if (current.getDistance(targetCoor) <= range) {
			ArrayList<Coordinate> affectedArea = calculateAffectedArea(army,
					scenario);
			for (Coordinate coor : affectedArea) {
				Army enemy = map.getArmy(coor.getLocationX(),
						coor.getLocationY());
				if (enemy != null) {
					if (group[enemy.getGroupID()].getSide() != group[army
							.getGroupID()].getSide()) {
						int previousEnemyHP = enemy.getHealth();
						int previousAllyHP = army.getHealth();

						int enemyRank = enemy.getRank();
						this.battle(army, enemy, false);

						if (enemy.isInAttackRange(army.getLocationX(),
								army.getLocationY())) {
							this.battle(enemy, army, false);
							int allyRank = army.getRank();
							int allyDead = previousAllyHP - army.getHealth();
							enemy.setExperience(enemy.getExperience()
									+ allyDead * allyRank, armyManager);
						}

						int enemyDead = previousEnemyHP - enemy.getHealth();
						army.setExperience(army.getExperience() + enemyDead
								* enemyRank, armyManager);

						army.setActionLeft(false);
						army.setMoveLeft(false);
					}
				}
			}
		}
	}

	@Override
	public void calculation(Army army, Scenario scenario) {
		BattleMap map = scenario.getBattleMap();
		Group[] group = scenario.getGroup();
		ArrayList<Coordinate> affectedArea = calculateAffectedArea(army,
				scenario);
		for (Coordinate coor : affectedArea) {
			Army enemy = map.getArmy(coor.getLocationX(), coor.getLocationY());
			if (enemy != null) {
				if (group[enemy.getGroupID()].getSide() != group[army
						.getGroupID()].getSide()) {
					int previousEnemyHP = enemy.getHealth();
					int previousAllyHP = army.getHealth();

					this.battle(army, enemy, true);

					if (enemy.isInAttackRange(army.getLocationX(),
							army.getLocationY())) {
						this.battle(enemy, army, true);
					}

					int allyDead = previousAllyHP - army.getHealth();
					int enemyDead = previousEnemyHP - enemy.getHealth();
					this.setAbilityPoint(enemyDead * enemy.getRank() - allyDead
							* army.getRank());

					army.setHealth(previousAllyHP);
					enemy.setHealth(previousEnemyHP);
				}
			}
		}
	}

	@Override
	public ArrayList<Coordinate> calculateAffectedArea(Army army,
			Scenario scenario) {
		ArrayList<Coordinate> temp = new ArrayList<Coordinate>();
		Coordinate target = this.getTarget();
		if (scenario.getBattleMap().isValidCoordinate(target)) {
			temp.add(target);
		}
		return temp;
	}

	public final void battle(Army army, Army enemy, boolean isCalculation) {
		int damageToEnemy;

		int army_hp = army.getHealth();
		int enemy_hp = enemy.getHealth();
		damageToEnemy = (army.getDamage() * army_hp - enemy.getTotalDefense()
				* enemy_hp);
		if (damageToEnemy < 0) {
			return;
		}
		enemy.setHealth(enemy_hp - damageToEnemy / 100, armyManager,
				isCalculation);
	}
}
